#include "./algorithm/base.h"
#include "./algorithm/files.h"
#include "./algorithm/cacheAccelerate.h"
#include "./algorithm/openmp.h"
#include "./algorithm/pthread.h"
#include "./algorithm/simd.h"
#include "./algorithm/test.h"
#include "./algorithm/camera.h"
int epoch = 2;
string DIR_PATH = "C:\Users\Emily2002\Downloads\parallel-project-master\img";

//Mat image1;
//Mat image2;
//
//int g_d = 15;
//int g_sigmaColor = 20;
//int g_sigmaSpace = 50;
//extern pthread_barrier_t barrier;
//
//void on_Trackbar(int, void *) {
//    bilateralFilter(image1, image2, g_d, g_sigmaColor, g_sigmaSpace);
//    imshow("output", image2);
//}

int main() {
#ifdef CAMERA
    useCamera();
#endif
    vector<string> imgPathList = getFilePathList(DIR_PATH);
#ifdef TEST
    //载入图像
//    Mat image = imread("/home/joshua/Projects/C++/Parallel/FH/img/9.jpg");
    Mat image1 = imread("/home/joshua/Projects/C++/Parallel/FH/img/2.jpg");
    if (image1.empty())
    {
        cout << "Could not load image ... " << endl;
        return  -1;
    }

    image2 = Mat::zeros(image1.rows, image1.cols, image1.type());
    bilateralFilter(image1, image2, g_d, g_sigmaColor, g_sigmaSpace);

    namedWindow("output");

    createTrackbar("核直径","output", &g_d, 50, on_Trackbar);
    createTrackbar("颜色空间方差","output", &g_sigmaColor, 100, on_Trackbar);
    createTrackbar("坐标空间方差","output", &g_sigmaSpace, 100, on_Trackbar);

//    imshow("input", image1);
    imshow("output", image2);

    waitKey(0);
#endif
#ifdef CV_GF
    {
        Timer give_me_a_name("OpenCVGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;
                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                //暴力实现
//                GaussianFilter(src, dst, Mask);
                GaussianBlur(src, dst,Size(3,3), 0.8);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif
#ifdef GF
    {
        Timer give_me_a_name("GaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;
                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                //暴力实现
                GaussianFilter(src, dst, Mask);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif
#ifdef CACHE_GF
    {
        Timer give_me_a_name("cacheGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;
                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                cacheGaussianFilter(src, dst, Mask);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif
#ifdef UNROLL_GF
    {
        Timer give_me_a_name("unrollGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;
                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                unrollGaussianFilter(src, dst, Mask);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif
#ifdef OMP_GF
    {
        Timer give_me_a_name("ompGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;
                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                ompGaussianFilter(src, dst, Mask);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif

#ifdef PTHREAD_GF
    {
        Timer give_me_a_name("pthreadGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat window;
                //获取二维高斯滤波模板
                generateGaussMask(window, cv::Size(3, 3), 0.8);
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                pthreadGaussianFilter(src, dst, window);
                dst.release();
                src.release();
                window.release();
            }
        }
    }
#endif

#ifdef AVX_GF
    {
        Timer give_me_a_name("avcGaussianFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat Mask;

                //获取二维高斯滤波模板
                generateGaussMask(Mask, cv::Size(3, 3), 0.8);

                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);

                if (src.empty()) {
                    return -1;
                }
                avxGaussianFilter(src, dst, Mask);
                dst.release();
                src.release();
                Mask.release();
            }
        }
    }
#endif

#ifdef SEPARATE_GF
    {
        Timer give_me_a_name("separateGaussianFilter");
        for (int e = 0; e < epoch; e++) {

            for (auto &i : imgPathList) {
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                //分离实现
                separateGaussianFilter(src, dst, 3, 0.8);
            }
        }
    }

#endif
#ifdef BIL_GF
    {
        Timer give_me_a_name("bilateralFilter");
        for (int e = 0; e < epoch; e++) {
            for (auto &i : imgPathList) {
                Mat dst;
                Mat src = imread(i, IMREAD_GRAYSCALE);
                if (src.empty()) {
                    return -1;
                }
                BilateralFilter(src, dst, Size(3, 3), 10, 30);
                //暴力实现
                dst.release();
                src.release();
            }
        }
    }
#endif

    //    cv::namedWindow("src");
    //    cv::imshow("src", src);
    //    cv::namedWindow("暴力实现", CV_WINDOW_NORMAL);
    //    cv::imshow("暴力实现", dst1);
    //    cv::namedWindow("分离实现", CV_WINDOW_NORMAL);
    //    cv::imshow("分离实现", dst2);
    //cv::imwrite("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Image Filtering\\GaussianFilter\\txt.jpg", dst2);
    //    cv::waitKey(0);
    return 0;
}
